package com.aaa.marketresearch.android.util.connector;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import com.aaa.marketresearch.android.util.SimpleLog;

import java.io.*;
import java.net.*;
import java.nio.charset.Charset;
import java.util.*;

/**
 * @author Nail
 */
public class HttpTextDataRequest extends AsyncTask<Void, Void, Void> {

    private Map<String, String> dataMap;
    private String dataText;
    private Context context;
    private URL url;
    private int timeout;
    private String responseData;

    private Boolean success;

    private List<IDataTextResponse> listeners;

    public HttpTextDataRequest(Context context) {
        this.context = context;
        this.timeout = 20000;
        // make sure cookies is turn on
        //CookieHandler.setDefault(new CookieManager());
    }

    public void addResponseListener(IDataTextResponse listener) {
        if (listeners == null) {
            this.listeners = new ArrayList<>();
        }
        this.listeners.add(listener);
    }

    public void setTimeout(int timeoutMillis) {
        this.timeout = timeoutMillis;
    }

    public void setURL(String url) {
        try {
            this.url = new URL(url);
        } catch (MalformedURLException ex) {
            SimpleLog.error("setURL io url: " + ex.toString());
        }
    }

    public void addData(String key, String value) {
        if (this.dataMap == null) {
            this.dataMap = new HashMap<String, String>();
        }
        this.dataMap.put(key, value);
    }

    public void addData(String text) {
        this.dataText = text;
    }


    public boolean send(Context context) {
        if (this.isNetworkAvailable()) {
            this.execute();
            return true;
        } else {
            AlertDialog.Builder alertDialog = new AlertDialog.Builder(context);
            alertDialog.setMessage("Сеть не доступна");
            alertDialog.setPositiveButton("Ok",
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {}
                    }
            );
            alertDialog.show();
            this.close();
            return false;
        }
    }

    private boolean isNetworkAvailable() {
        ConnectivityManager cm = (ConnectivityManager) this.context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = cm.getActiveNetworkInfo();
        if (networkInfo != null && networkInfo.isConnected()) {
            return true;
        }
        return false;
    }


    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    @Override
    protected Void doInBackground(Void... params) {
        HttpURLConnection connect = null;
        try {
            this.success = false;
            connect = (HttpURLConnection) this.url.openConnection();

            if (this.dataMap == null && this.dataText == null) {
                connect.setRequestMethod("GET");
                connect.setRequestProperty("Content-length", "0");
                connect.setUseCaches(false);
                connect.setAllowUserInteraction(false);
                connect.setConnectTimeout(timeout);
                connect.setReadTimeout(timeout);
                connect.connect();
            } else {
                connect.setRequestMethod("POST");
                connect.setUseCaches(false);
                connect.setDoInput(true);
                connect.setDoOutput(true);
                connect.setAllowUserInteraction(false);
                connect.setConnectTimeout(timeout);
                connect.setReadTimeout(timeout);

                final String content;
                if (this.dataMap != null) {
                    connect.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
                    content = this.getUrlParameters();

                } else {
                    connect.setRequestProperty("Content-Type", "application/json; charset=utf-8");
                    content = dataText;
                }

                byte[] data = content.getBytes(Charset.forName("UTF-8"));
                int length = data.length;
                connect.setFixedLengthStreamingMode(length);

                //Send request
                DataOutputStream wr = new DataOutputStream(connect.getOutputStream());
                wr.write(data, 0, length);
                wr.flush();
                wr.close();
            }

            this.responseData = null;
            int status = connect.getResponseCode();

            switch (status) {
                case 200:
                case 201:
                    if (this.listeners != null) {
                        InputStream inputStream = connect.getInputStream();

                        if (inputStream != null) {
                            final BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
                            final StringBuilder sb = new StringBuilder();
                            String line;
                            while ((line = br.readLine()) != null) {
                                sb.append(line + "\n");
                            }
                            br.close();
                            this.responseData = sb.toString();
                        } else {
                            this.responseData = "";
                        }
                    }
                    this.success = true;
            }
        } catch (MalformedURLException ex) {
            SimpleLog.error("doInBackground io url: " + ex.toString());
        } catch (IOException ex) {
            SimpleLog.error("doInBackground io ex: " + ex.toString());
        } finally {
            if (connect != null) connect.disconnect();
        }
        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        super.onPostExecute(result);
        this.close();
    }

    private void close() {
        if (this.listeners != null) {
            for (IDataTextResponse listener : this.listeners) {
                if (this.success!= null && this.success) {
                    listener.onTextResponse(this.responseData);
                } else {
                    listener.onError();
                }
            }
        }
    }


    private String getUrlParameters() {
        StringBuilder stringBuilder = new StringBuilder();
        Set<String> keySet = this.dataMap.keySet();
        for (Iterator<String> itKey = keySet.iterator(); itKey.hasNext();) {
            String key = itKey.next();
            String value = this.dataMap.get(key);

            String urlKey = null;
            String urlValue = null;

            try {
                urlKey = URLEncoder.encode(key, "UTF-8");
                urlValue = URLEncoder.encode(value, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                SimpleLog.error(e.toString());
            }

            stringBuilder.append(urlKey).append("=").append(urlValue);
            if (itKey.hasNext()) {
                stringBuilder.append("&");
            }
        }
        return stringBuilder.toString();
    }

}
